package aps.module_Machines;

//Java
import net.minecraft.src.Block;
import net.minecraft.src.Container;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ICrafting;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ILiquidTank;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidContainerRegistry;
import net.minecraftforge.liquids.LiquidStack;
import net.minecraftforge.liquids.LiquidTank;
import aps.module_Core.GuiIDs;
import aps.module_Core.InventoryAPS;
import aps.module_Core.TileEntityAPSPowered;
import aps.module_Core.module_Core.APSBlockTypes;
import buildcraft.BuildCraftCore;
import buildcraft.api.gates.Action;
import buildcraft.api.gates.IAction;
import buildcraft.api.gates.IActionReceptor;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.core.IMachine;
import buildcraft.core.triggers.ActionMachineControl;
//Vanilla Minecraft
//Buildcraft
//APS

public class TileEntityMagmafier extends TileEntityAPSPowered implements IPowerReceptor, IInventory, ITankContainer, IActionReceptor, IMachine
{
	static int LavaID = Block.lavaStill.blockID;
	static int LavaCapacity = LiquidContainerRegistry.BUCKET_VOLUME * 10;
	static int BlockToLavaRatio = 16;
	static int BlockMeltEnergy = 1250;
	static int BlockCapacity = 10 * BlockToLavaRatio;
	static int LiquidSideTex = 3;
	
	InventoryAPS Inventory;
	float PowerLevel;
	int BlockLevel;
	ILiquidTank tank = new LiquidTank(LavaCapacity);
	
	ActionMachineControl.Mode lastMode = ActionMachineControl.Mode.Unknown;
	
	public TileEntityMagmafier()
	{
		super( 0, 36, 1, 2, 0, 1, BlockMeltEnergy, 1, BlockMeltEnergy, APSBlockTypes.Machine);
		hasGUI = true;
		GuiID = GuiIDs.GUI_MAGMAFIER;
		Inventory = new InventoryAPS(1, "magmafierinput");
		PowerLevel = 0;
		BlockLevel = 0;
	}
	
	int LavaCounter = 0;
	@Override
	public void updateEntity()
	{
		super.updateEntity();
		
		ItemStack itemInInventory = Inventory.getStackInSlot(0);
		
		if (itemInInventory != null && BlockLevel < BlockCapacity && module_Machines.isMeltable(itemInInventory))
		{
			if(BlockCapacity - BlockLevel < itemInInventory.stackSize)
			{
				int i = BlockCapacity - BlockLevel;
				BlockLevel = BlockCapacity;
				Inventory.decrStackSize(0, i);
			}
			else
			{
				BlockLevel += itemInInventory.stackSize;
				Inventory.setInventorySlotContents(0, null);
			}
		}
		
		if(lastMode == ActionMachineControl.Mode.On || lastMode == ActionMachineControl.Mode.Loop || lastMode == ActionMachineControl.Mode.Unknown)
        {
			PowerLevel += powerProvider.useEnergy(1, BlockMeltEnergy - PowerLevel, true);
			//PowerLevel += powerProvider.useEnergy(0, 500, true);
			if (BlockLevel > 0 && PowerLevel >= BlockMeltEnergy)
			{
				//LavaLevel += (LavaCapacity / 10) / BlockToLavaRatio;
				tank.fill(new LiquidStack(LavaID, (LavaCapacity / 10) / BlockToLavaRatio), true);
				BlockLevel--;
				PowerLevel -= BlockMeltEnergy;	
			}
        }
		if(lastMode == ActionMachineControl.Mode.On) lastMode = ActionMachineControl.Mode.Off;
	}
	
	public int powerRequest()
	{
		if (BlockLevel > 0) //is there resource in the store?
		{
			//These are separate because an OR statement will spit out an NullPointer exception  if the tank is null
			if (tank.getLiquid() == null) //Tank is empty
				return BlockMeltEnergy;
			if (tank.getLiquid().amount < this.LavaCapacity) //do we have room to make more lava?
				return BlockMeltEnergy;
		}
		return 0;
	}

	public int fill(ForgeDirection from, LiquidStack resource, boolean doFill) {
		return fill(0, resource, doFill);
	}

	public int fill(int tankIndex, LiquidStack resource, boolean doFill) {
		return this.tank.fill(resource, doFill);
	}

	public ILiquidTank[] getTanks(ForgeDirection direction) {
		return new ILiquidTank[] {tank};
	}
	
	public ILiquidTank getTank(ForgeDirection direction, LiquidStack liquidStack){
		return this.tank;
	}

	public LiquidStack drain(ForgeDirection from, int quantityMax, boolean doDrain)
	{
		return drain(0, quantityMax, doDrain);
	}
	
	public LiquidStack drain(int tankIndex, int maxEmpty, boolean doDrain)
	{
		//System.out.println("Draining");
		return drain(maxEmpty, doDrain);
	}
	
	public LiquidStack drain(int maxDrain, boolean doDrain) 
	{
		return this.tank.drain(maxDrain, doDrain);
	}
	
	@Override
	public void readFromNBT(NBTTagCompound nbttagcompound)
    {
    	super.readFromNBT(nbttagcompound);
		
    	PowerLevel = nbttagcompound.getFloat("powerlevel");
    	int lavaLevel = nbttagcompound.getInteger("lavalevel"); tank.fill(new LiquidStack(LavaID, lavaLevel), true);
    	BlockLevel = nbttagcompound.getInteger("blocklevel");
    	if (nbttagcompound.hasKey("inputslotitem")) {
    		NBTTagCompound cpt = nbttagcompound.getCompoundTag("inputslotitem"); //dAkshEN3: Changed from 'itemInInventory'. MIGHT HAVE BEEN CAUSE OF CHUNK ERRORS
    		Inventory.addItemStackToInventory((ItemStack)ItemStack.loadItemStackFromNBT(cpt));
    	}
    }
	
	@Override
    public void writeToNBT(NBTTagCompound nbttagcompound) {
    	super.writeToNBT(nbttagcompound);
    	
		nbttagcompound.setFloat("powerlevel", PowerLevel);
    	nbttagcompound.setInteger("lavalevel", tank.getLiquid() == null ? 0 : tank.getLiquid().amount);
    	nbttagcompound.setInteger("blocklevel", BlockLevel);
    	
    	if (Inventory.getStackInSlot(0) != null) {
    		NBTTagCompound cpt = new NBTTagCompound();
    		Inventory.getStackInSlot(0).writeToNBT(cpt);
    		nbttagcompound.setTag("inputslotitem", cpt);
    	}
    }
	
	public IInventory getInventory() {return Inventory;}
	
	public float getScaledLiquidQuantity(int MaxLevel) {return ((float)(tank.getLiquid() == null ? 0 : tank.getLiquid().amount) / (float) LavaCapacity) * MaxLevel;}
	
	public float getScaledBlockQuantity(int MaxLevel) {return ((float) BlockLevel / (float) BlockCapacity) * MaxLevel;}
	
	public float getScaledPowerLevel(int MaxLevel) {return ((float) PowerLevel / (float) BlockMeltEnergy) * MaxLevel;}

	@Override
	public void kill() {}
	
	//@Override
	//public GuiScreen getGUI(EntityPlayer entityplayer) {
	//	return new GuiMagmafier(this, entityplayer.inventory);
	//}

	@Override
	public boolean isActive() {
		return BlockLevel > 0; // || (tank.getLiquid() == null ? 0 : tank.getLiquid().amount) < LavaCapacity;
	}

	@Override
	public boolean manageLiquids() {return true;}

	@Override
	public boolean manageSolids() {return true;}

	@Override
	public boolean allowActions() {return true;}

	//@Override
	public void actionActivated(Action action) {
		if (action == BuildCraftCore.actionOn) {
			lastMode = ActionMachineControl.Mode.On;
		} else if (action == BuildCraftCore.actionOff) {
			lastMode = ActionMachineControl.Mode.Off;
		} else if (action == BuildCraftCore.actionLoop) {
			lastMode = ActionMachineControl.Mode.Loop;
		}		
	}

	@Override
	public int getSizeInventory() {
		return Inventory.getSizeInventory();
	}

	@Override
	public ItemStack getStackInSlot(int i) {
		return Inventory.getStackInSlot(i);
	}

	@Override
	public ItemStack decrStackSize(int i, int j) {
		return Inventory.decrStackSize(i, j);
	}

	@Override
	public void setInventorySlotContents(int i, ItemStack itemstack) {
		Inventory.setInventorySlotContents(i, itemstack);
	}

	@Override
	public String getInvName() {
		return Inventory.getInvName();
	}

	@Override
	public int getInventoryStackLimit() {
		return Inventory.getInventoryStackLimit();
	}

	@Override
	public boolean isUseableByPlayer(EntityPlayer entityplayer) {
		return Inventory.isUseableByPlayer(entityplayer);
	}

	@Override
	public void openChest() {
		Inventory.openChest();
	}

	@Override
	public void closeChest() {
		Inventory.closeChest();
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int var1) {
		return null;
	}

	@Override
	public void actionActivated(IAction action) {
		//
	}
	
	public void sendGUIUpdates(Container container, ICrafting iCrafting)
	{
		iCrafting.sendProgressBarUpdate(container, 0, (int)this.PowerLevel); 
		iCrafting.sendProgressBarUpdate(container, 1, this.BlockLevel);
		iCrafting.sendProgressBarUpdate(container, 2, (this.tank.getLiquid() == null ? 0 : tank.getLiquid().amount));
	}
	
	public void getGUIUpdates(int channel, int i)
	{
		switch (channel)
		{
			case 0: //Power level
				this.PowerLevel = (float)i;
				break;
			case 1: //block level
				this.BlockLevel = i;
				break;
			case 2: //Lava Level
				this.tank = new LiquidTank(LavaID, i, LavaCapacity);
				break;
		}
	}
}